/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package beans;

import java.sql.*;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Calendar;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import javax.faces.validator.ValidatorException;
import javax.servlet.http.HttpSession;

public class Datum {

    private String dan;
    private String mesec;
    private String godina;

    private String namena;
    private String sala;
    private String tod;
    private String tdo;

    private ArrayList<SelectItem> satiItems = new ArrayList<SelectItem>();
    {for (int i=8;i<23;i++) satiItems.add(new SelectItem(i));}

    private SelectItem[] saleItems = {
        new SelectItem("laboratorija 25"),
        new SelectItem("laboratorija 26"),
        new SelectItem("laboratorija 60"),
        new SelectItem("ucionica 61")
    };

    public String rezervisi(){
        FacesContext context = FacesContext.getCurrentInstance();
        Time timeod=Time.valueOf(tod+":00:00");
        Time timedo=Time.valueOf(tdo+":00:00");

        Date rzrv=Date.valueOf(godina+"-"+mesec+"-"+dan);
        Date nowd= new Date(Calendar.getInstance().getTimeInMillis());
        Timestamp now=new Timestamp(Calendar.getInstance().getTimeInMillis());

        if(rzrv.before(nowd)){
            context.addMessage(null, new FacesMessage("Изабрани датум је већ поршао !"));
            return null;
        }
        if(timeod.compareTo(timedo)>=0){
            context.addMessage(null, new FacesMessage("Невалидно време резервације !"));
            return null;
        }
        Connection con = null;
        ResultSet rs = null;
        Statement stmt = null;
        try {
            con = DB.getConnection();
            stmt = con.createStatement();

            rs = stmt.executeQuery("select razlog from neradni_dani where datum='"+ Date.valueOf(godina+"-"+mesec+"-"+dan) +"';");
            if(rs.next()){
                context.addMessage(null, new FacesMessage("Za ovaj dan nije dozvoljena rezervacija, razlog je: " + rs.getString("razlog")));
                stmt.close();con.close();
                return null;
            }//Ako je dan neradni ne moze da se unese rezervacija za taj dan

            HttpSession session = (HttpSession) context.getExternalContext().getSession(false);
            int sid=((Sala)session.getAttribute("sala")).getSid();

            rs = stmt.executeQuery("select * from rezervacija where datum='"+ Date.valueOf(godina+"-"+mesec+"-"+dan) +"'and sid="+sid+";");
            while(rs.next()){
                Time tableod=rs.getTime("PocevOd");//pocetno vreme
                long domills = tableod.getTime();
                domills+=rs.getInt("Trajanje")*60*60*1000;
                Time tabledo=new Time(domills);//krajnje vreme
                if(timeod.compareTo(tableod)>=0 && timeod.compareTo(tabledo)<0  ||
                   timedo.compareTo(tableod)>0  && timedo.compareTo(tabledo)<=0 ||
                   timeod.before(tableod) && timedo.after(tabledo)
                   ){
                    dan=mesec=godina="";
                    tod=tdo="8";
                    namena="";
                    context.addMessage(null, new FacesMessage("Не може , сала заузета од :"+ tableod.toString() +" до:"+ tabledo.toString()));
                    stmt.close();con.close();
                    return null;
                }
            }//ako je sala zauzeta u zadatom periodu
            //OBAVI REZERVACIJU
            

            //rs = stmt.executeQuery("select sid from sala where naziv='"+ sala +"';");
            //int sid=0;
            //if(rs.next())sid=rs.getInt("sid");

            session = (HttpSession) context.getExternalContext().getSession(false);
            int kid=((User)session.getAttribute("user")).getKid();

            int traj = timedo.getHours() - timeod.getHours();

            stmt.executeUpdate(
            "INSERT INTO rezervacija (sid, korisnik, Namena,Datum,PocevOd,Trajanje,datumRezervisanja) VALUES"+
            "('"+sid+"','"+kid+"','"+namena+"','"+Date.valueOf(godina+"-"+mesec+"-"+dan)+"','"+timeod+"','"+traj+"','"+now+"');"
            );
            context.addMessage(null, new FacesMessage("Резервација Обављена"));
            dan=mesec=godina="";
            tod=tdo="8";
            namena="";
            stmt.close();con.close();
        }catch (Exception e){
            if (con != null) {
                try {
                    con.close();
                } catch (Exception ex) {}
            }
            context.addMessage(null, new FacesMessage(e.getLocalizedMessage()));
            return "error";
        }
        return null;
    }

    public String rezervisiKonkretnu(){
        FacesContext context = FacesContext.getCurrentInstance();
        Time timeod=Time.valueOf(tod+":00:00");
        Time timedo=Time.valueOf(tdo+":00:00");

        Date rzrv=Date.valueOf(godina+"-"+mesec+"-"+dan);
        Date nowd= new Date(Calendar.getInstance().getTimeInMillis());
        Timestamp now=new Timestamp(Calendar.getInstance().getTimeInMillis());

        if(rzrv.before(nowd)){
            context.addMessage(null, new FacesMessage("Изабрани датум је већ поршао !"));
            return null;
        }
        if(timeod.compareTo(timedo)>=0){
            context.addMessage(null, new FacesMessage("Невалидно време резервације !"));
            return null;
        }
        Connection con = null;
        ResultSet rs = null;
        Statement stmt = null;
        try {
            con = DB.getConnection();
            stmt = con.createStatement();

            rs = stmt.executeQuery("select razlog from neradni_dani where datum='"+ Date.valueOf(godina+"-"+mesec+"-"+dan) +"';");
            if(rs.next()){
                context.addMessage(null, new FacesMessage("Za ovaj dan nije dozvoljena rezervacija, razlog je: " + rs.getString("razlog")));
                stmt.close();con.close();
                return null;
            }//Ako je dan neradni ne moze da se unese rezervacija za taj dan

            rs = stmt.executeQuery("select sid from sala where naziv='"+ sala +"';");
            int sid=0;
            if(rs.next())sid=rs.getInt("sid");

            rs = stmt.executeQuery("select * from rezervacija where datum='"+ Date.valueOf(godina+"-"+mesec+"-"+dan) +"'and sid="+sid+";");
            while(rs.next()){
                Time tableod=rs.getTime("PocevOd");
                long domills = tableod.getTime();
                domills+=rs.getInt("Trajanje")*60*60*1000;
                Time tabledo=new Time(domills);
                if(timeod.compareTo(tableod)>=0 && timeod.compareTo(tabledo)<0  ||
                   timedo.compareTo(tableod)>0  && timedo.compareTo(tabledo)<=0 ||
                   timeod.before(tableod) && timedo.after(tabledo)
                   ){
                    dan=mesec=godina="";
                    tod=tdo="8";
                    namena="";
                    context.addMessage(null, new FacesMessage("Не може , сала заузета од :"+ tableod.toString() +" до:"+ tabledo.toString()));
                    stmt.close();con.close();
                    return null;
                }
            }//ako je sala zauzeta u zadatom periodu
            //OBAVI REZERVACIJU
            

            HttpSession session = (HttpSession) context.getExternalContext().getSession(false);
            int kid=((User)session.getAttribute("user")).getKid();

            int traj = timedo.getHours() - timeod.getHours();

            stmt.executeUpdate(
            "INSERT INTO rezervacija (sid, korisnik, Namena,Datum,PocevOd,Trajanje,datumRezervisanja) VALUES"+
            "('"+sid+"','"+kid+"','"+namena+"','"+Date.valueOf(godina+"-"+mesec+"-"+dan)+"','"+timeod+"','"+traj+"','"+now+"');"
            );
            context.addMessage(null, new FacesMessage("Резервација Обављена"));
            dan=mesec=godina="";
            tod=tdo="8";
            namena="";
            stmt.close();con.close();
        }catch (Exception e){
            if (con != null) {
                try {
                    con.close();
                } catch (Exception ex) {}
            }
            context.addMessage(null, new FacesMessage(e.getLocalizedMessage()));
            return "error";
        }
        return null;
    }

    public String rezervisiKonkretnuZaKorisnika(){
        FacesContext context = FacesContext.getCurrentInstance();
        Time timeod=Time.valueOf(tod+":00:00");
        Time timedo=Time.valueOf(tdo+":00:00");

        Date rzrv=Date.valueOf(godina+"-"+mesec+"-"+dan);
        Date nowd= new Date(Calendar.getInstance().getTimeInMillis());
        Timestamp now=new Timestamp(Calendar.getInstance().getTimeInMillis());

        if(rzrv.before(nowd)){
            context.addMessage(null, new FacesMessage("Изабрани датум је већ поршао !"));
            return null;
        }
        if(timeod.compareTo(timedo)>=0){
            context.addMessage(null, new FacesMessage("Невалидно време резервације !"));
            return null;
        }
        Connection con = null;
        ResultSet rs = null;
        Statement stmt = null;
        try {
            con = DB.getConnection();
            stmt = con.createStatement();

            rs = stmt.executeQuery("select razlog from neradni_dani where datum='"+ Date.valueOf(godina+"-"+mesec+"-"+dan) +"';");
            if(rs.next()){
                context.addMessage(null, new FacesMessage("Za ovaj dan nije dozvoljena rezervacija, razlog je: " + rs.getString("razlog")));
                stmt.close();con.close();
                return null;
            }//Ako je dan neradni ne moze da se unese rezervacija za taj dan

            rs = stmt.executeQuery("select sid from sala where naziv='"+ sala +"';");
            int sid=0;
            if(rs.next())sid=rs.getInt("sid");

            rs = stmt.executeQuery("select * from rezervacija where datum='"+ Date.valueOf(godina+"-"+mesec+"-"+dan) +"'and sid="+sid+";");
            while(rs.next()){
                Time tableod=rs.getTime("PocevOd");
                long domills = tableod.getTime();
                domills+=rs.getInt("Trajanje")*60*60*1000;
                Time tabledo=new Time(domills);
                if(timeod.compareTo(tableod)>=0 && timeod.compareTo(tabledo)<0  ||
                   timedo.compareTo(tableod)>0  && timedo.compareTo(tabledo)<=0 ||
                   timeod.before(tableod) && timedo.after(tabledo)
                   ){
                    dan=mesec=godina="";
                    tod=tdo="8";
                    namena="";
                    context.addMessage(null, new FacesMessage("Не може , сала заузета од :"+ tableod.toString() +" до:"+ tabledo.toString()));
                    stmt.close();con.close();
                    return null;
                }
            }//ako je sala zauzeta u zadatom periodu
            //OBAVI REZERVACIJU
    

            HttpSession session = (HttpSession) context.getExternalContext().getSession(false);
            int kid=((Korisnik)session.getAttribute("kor")).getKid();

            int traj = timedo.getHours() - timeod.getHours();

            stmt.executeUpdate(
            "INSERT INTO rezervacija (sid, korisnik, Namena,Datum,PocevOd,Trajanje,datumRezervisanja) VALUES"+
            "('"+sid+"','"+kid+"','"+namena+"','"+Date.valueOf(godina+"-"+mesec+"-"+dan)+"','"+timeod+"','"+traj+"','"+now+"');"
            );
            context.addMessage(null, new FacesMessage("Резервација Обављена"));
            dan=mesec=godina="";
            tod=tdo="8";
            namena="";
            stmt.close();con.close();
        }catch (Exception e){
            if (con != null) {
                try {
                    con.close();
                } catch (Exception ex) {}
            }
            context.addMessage(null, new FacesMessage(e.getLocalizedMessage()));
            return "error";
        }
        return null;
    }

    public String raspored() {
        Date datum = Date.valueOf(godina+"-"+mesec+"-"+dan);//uneseni datum za koji treba ispisati nedelju
        int day = datum.getDay();//Sunday=0,Monday=1,Tuesday=2,Wednesday=3,Thursday=4,Friday=5,Saturday=6
        int sub;
        if(day==0)sub=6;
        else sub=day-1;
        long submills = sub*24*60*60*1000;
        long datemills = datum.getTime();
        datemills-=submills;
        //IZVUCI SVE DANE U NEDELJI U LISTU
        ArrayList<Date> datumi = new ArrayList<Date>();
        for(int i=0;i<7;i++){//lista datuma za koje treba izvrsiti razmatranje
            datumi.add(new Date(datemills));
            day = (new Date(datemills)).getDay();
            datemills+=24*60*60*1000;
        }
        //ZA SVAKI DAN U NEDELJI VIDI BAZU
        ArrayList[] dani = new ArrayList[7];
        for(int i=0;i<dani.length;i++){//za svaki dan bice kreirana nova lista rezervacija
            dani[i] = new ArrayList<Rezervacija>();
        }

        FacesContext context = FacesContext.getCurrentInstance();
        HttpSession session = (HttpSession) context.getExternalContext().getSession(false);
        Connection con = null;
        ResultSet rs = null;
        Statement stmt = null;
        int sid = ((Sala)session.getAttribute("sala")).getSid();//dohvata se sala iz sesije
        try {
            con = DB.getConnection();
            stmt = con.createStatement();
            for(int i=0;i<datumi.size();i++){//za svaki datum ponaosob popunjava postojece rezervacije
                rs = stmt.executeQuery("select * from rezervacija where datum='"+ datumi.get(i) +"' and sid='"+sid+"';");
                while(rs.next()){
                    Time vreme1=rs.getTime("PocevOd");
                    long timemills = vreme1.getTime();
                    timemills+=rs.getInt("Trajanje")*60*60*1000;
                    Time vreme2=new Time(timemills);
                    String kid=rs.getString("korisnik");
                        ResultSet nrs = null;
                        Statement nstmt = con.createStatement();
                        nrs = nstmt.executeQuery("select ime from korisnik where kid='"+ kid +"';");
                        String kor=null;
                        if(nrs.next())kor=nrs.getString("ime");
                        nrs.close();nstmt.close();
                    String nam=rs.getString("namena");
                    dani[i].add(new Rezervacija(vreme1,vreme2,kor,nam,false,datumi.get(i)));
                }
                rs = stmt.executeQuery("select razlog from neradni_dani where datum='"+ datumi.get(i) +"';");
                if(rs.next())dani[i].add(new Rezervacija(Time.valueOf("08:00:00"),Time.valueOf("22:00:00"),rs.getString("razlog"),"",false,datumi.get(i)));
            }
            //POPUNI SLOBODNE TERMINE U DANIMA
            ArrayList<Rezervacija> tmp = new ArrayList<Rezervacija>();
            for(int i=0;i<dani.length;i++){//za svaki dan ponaosob
                tmp.clear();
                java.util.Collections.sort(dani[i]);
                Time start=Time.valueOf("08:00:00");
                Time end  =Time.valueOf("22:00:00");
                for(int j=0;j<dani[i].size();j++){//za svaku rezervaciju ponaosob iz dana
                    Time stime =((Rezervacija)dani[i].get(j)).getStart();
                    Time etime =((Rezervacija)dani[i].get(j)).getEnd();
                    if(start.before(stime)){
                        tmp.add(new Rezervacija(start,stime,null,null,true,datumi.get(i)));
                    }
                    start=etime;
                }
                if(start.before(end)){//ako se zadnja rezervacija za neki dan zavrsava pre 22h
                    tmp.add(new Rezervacija(start,end,null,null,true,datumi.get(i)));
                }
                dani[i].addAll(tmp);//spaja u jednu listu dve liste
                java.util.Collections.sort(dani[i]);//sortira dve liste
            }
            session.setAttribute("datumi", datumi);
            session.setAttribute("dani", dani);
            stmt.close();
            con.close();
        }catch (Exception e){
            if (con != null) {
                try {
                    con.close();
                } catch (Exception ex) {}
            }
            context.addMessage(null, new FacesMessage(e.getLocalizedMessage()));
            return "error";
        }
        User u=(User)session.getAttribute("user");

        dan=mesec=godina="";
        //return u.klabkonkretna();
        return null;
    }

    public String rezervisiIztabele(){
        FacesContext context = FacesContext.getCurrentInstance();
        Time timeod=Time.valueOf(tod+":00:00");
        Time timedo=Time.valueOf(tdo+":00:00");

        Date rzrv=Date.valueOf(godina+"-"+mesec+"-"+dan);
        Date nowd= new Date(Calendar.getInstance().getTimeInMillis());
        Timestamp now=new Timestamp(Calendar.getInstance().getTimeInMillis());

        if(rzrv.before(nowd)){
            context.addMessage(null, new FacesMessage("Изабрани датум је већ поршао !"));
            return null;
        }
        if(timeod.compareTo(timedo)>=0){
            context.addMessage(null, new FacesMessage("Невалидно време резервације !"));
            return null;
        }
        Connection con = null;
        ResultSet rs = null;
        Statement stmt = null;
        try {
            con = DB.getConnection();
            stmt = con.createStatement();

            rs = stmt.executeQuery("select razlog from neradni_dani where datum='"+ Date.valueOf(godina+"-"+mesec+"-"+dan) +"';");
            if(rs.next()){
                context.addMessage(null, new FacesMessage("Za ovaj dan nije dozvoljena rezervacija, razlog je: " + rs.getString("razlog")));
                stmt.close();con.close();
                return null;
            }//Ako je dan neradni ne moze da se unese rezervacija za taj dan

            HttpSession session = (HttpSession) context.getExternalContext().getSession(false);
            int sid=((Sala)session.getAttribute("sala")).getSid();

            rs = stmt.executeQuery("select * from rezervacija where datum='"+ Date.valueOf(godina+"-"+mesec+"-"+dan) +"' and sid="+sid+";");
            while(rs.next()){
                Time tableod=rs.getTime("PocevOd");//pocetno vreme
                long domills = tableod.getTime();
                domills+=rs.getInt("Trajanje")*60*60*1000;
                Time tabledo=new Time(domills);//krajnje vreme
                if(timeod.compareTo(tableod)>=0 && timeod.compareTo(tabledo)<0  ||
                   timedo.compareTo(tableod)>0  && timedo.compareTo(tabledo)<=0 ||
                   timeod.before(tableod) && timedo.after(tabledo)
                   ){
                    dan=mesec=godina="";
                    tod=tdo="8";
                    namena="";
                    context.addMessage(null, new FacesMessage("Не може , сала заузета од :"+ tableod.toString() +" до:"+ tabledo.toString()));
                    stmt.close();con.close();
                    return null;
                }
            }//ako je sala zauzeta u zadatom periodu
            //OBAVI REZERVACIJU
            

            //rs = stmt.executeQuery("select sid from sala where naziv='"+ sala +"';");
            //int sid=0;
            //if(rs.next())sid=rs.getInt("sid");

            session = (HttpSession) context.getExternalContext().getSession(false);
            int kid=((User)session.getAttribute("user")).getKid();

            int traj = timedo.getHours() - timeod.getHours();

            stmt.executeUpdate(
            "INSERT INTO rezervacija (sid, korisnik, Namena,Datum,PocevOd,Trajanje,datumRezervisanja) VALUES"+
            "('"+sid+"','"+kid+"','"+namena+"','"+Date.valueOf(godina+"-"+mesec+"-"+dan)+"','"+timeod+"','"+traj+"','"+now+"');"
            );
            context.addMessage(null, new FacesMessage("Резервација Обављена"));
            dan=mesec=godina="";
            tod=tdo="8";
            namena="";
            stmt.close();con.close();
        }catch (Exception e){
            if (con != null) {
                try {
                    con.close();
                } catch (Exception ex) {}
            }
            context.addMessage(null, new FacesMessage(e.getLocalizedMessage()));
            return "error";
        }
        return null;
    }


    public void validateDan(FacesContext context,UIComponent componentToValidate, Object value) throws ValidatorException {
            String vdan = (String)value;
            int chk=-1;
            try{
                chk = Integer.parseInt(vdan);
            }catch(Exception e){}
            if(chk>0 && chk<32)return;
            FacesMessage message=new FacesMessage("Неправилно унет дан !");
			message.setSeverity(FacesMessage.SEVERITY_ERROR);
			throw new ValidatorException(message);
    }
    public void validateMesec(FacesContext context,UIComponent componentToValidate, Object value) throws ValidatorException {
            String vmesec = (String)value;
            int chk=-1;
            try{
                chk = Integer.parseInt(vmesec);
            }catch(Exception e){}
            if(chk>0 && chk<13)return;
            FacesMessage message=new FacesMessage("Неправилно унет месец !");
			message.setSeverity(FacesMessage.SEVERITY_ERROR);
			throw new ValidatorException(message);
    }
    public void validateGodina(FacesContext context,UIComponent componentToValidate, Object value) throws ValidatorException {
            String vgodina = (String)value;
            int chk=-1;
            try{
                chk = Integer.parseInt(vgodina);
            }catch(Exception e){}
            if(chk>0)return;
            FacesMessage message=new FacesMessage("Неправилно унета година !");
			message.setSeverity(FacesMessage.SEVERITY_ERROR);
			throw new ValidatorException(message);
    }


    //GETTERS AND SETTERS
    /**
     * @return the dan
     */
    public String getDan() {
        return dan;
    }

    /**
     * @param dan the dan to set
     */
    public void setDan(String dan) {
        this.dan = dan;
    }

    /**
     * @return the mesec
     */
    public String getMesec() {
        return mesec;
    }

    /**
     * @param mesec the mesec to set
     */
    public void setMesec(String mesec) {
        this.mesec = mesec;
    }

    /**
     * @return the godina
     */
    public String getGodina() {
        return godina;
    }

    /**
     * @param godina the godina to set
     */
    public void setGodina(String godina) {
        this.godina = godina;
    }
    /**
     * @return the satiItems
     */
    public ArrayList<SelectItem> getSatiItems() {
        return satiItems;
    }

    /**
     * @return the saleItems
     */
    public SelectItem[] getSaleItems() {
        return saleItems;
    }

    /**
     * @return the sala
     */
    public String getSala() {
        return sala;
    }

    /**
     * @param sala the sala to set
     */
    public void setSala(String sala) {
        this.sala = sala;
    }

    /**
     * @return the tod
     */
    public String getTod() {
        return tod;
    }

    /**
     * @param tod the tod to set
     */
    public void setTod(String tod) {
        this.tod = tod;
    }

    /**
     * @return the tdo
     */
    public String getTdo() {
        return tdo;
    }

    /**
     * @param tdo the tdo to set
     */
    public void setTdo(String tdo) {
        this.tdo = tdo;
    }

    /**
     * @return the namena
     */
    public String getNamena() {
        return namena;
    }

    /**
     * @param namena the namena to set
     */
    public void setNamena(String namena) {
        this.namena = namena;
    }

}

